from django.shortcuts import render
from django.views import View
import json
from django import http
from qingmei_mall.utils.response_code import RETCODE
from goods.models import SKU
from django_redis import get_redis_connection
from qingmei_mall.utils import meiduo_json
from users.models import Address
from django.contrib.auth.mixins import LoginRequiredMixin
from .models import OrderInfo,OrderGoods
from datetime import datetime
from django.db import transaction
import time
from django.core.paginator import Paginator
import random


class OrderView(LoginRequiredMixin,View):
    def get(self,request):
        # 查询收货地址
        addresses = []
        user = request.user
        # [<Address 1>,<Address 2>,<Address 3>]
        address_list = Address.objects.filter(user_id=user.id,is_delete=False)

        # 查询购物车数据
        cart_cli = get_redis_connection("cart")
        # 商品id:数量  {1:1,2:2,3:3}
        cart_dict = cart_cli.hgetall("cart_%d"%user.id)
        # 选中状态 [1,2]
        selectes = cart_cli.smembers("selected_%d"%user.id)
        # 判断商品是否在选中列表中 {1:1,2:2}
        cart_dict = {int(sku_id):int(count) for sku_id,count in cart_dict.items() if sku_id in selectes}

        # for sku_id, count in cart_dict.items():
        #     if sku_id in selectes:
        #        cart_dict[int(sku_id)] = int(count)

        skus = SKU.objects.filter(id__in=cart_dict.keys(),is_launched=True)
        sku_list = []
        # 总数量
        total_count = 0
        # 总金额
        total_money = 0
        # 运费
        freight = 10
        # [1,2]
        for sku in skus:
            # 每次遍历加上库存商品的购买数量
            total_count += cart_dict[sku.id]
            # 小计
            total_amount = sku.price*cart_dict[sku.id]
            # 总金额
            total_money += total_amount
            sku_list.append({
                "id":sku.id,
                "default_image":sku.default_image.url,
                "name":sku.name,
                "price":sku.price,
                "count":cart_dict[sku.id],
                "total_amount":total_amount,
            })
        # 实付款
        pay_money = total_money + freight
        context = {
            "addresses":address_list,
            "default_address_id":user.default_address_id,
            "sku_list":sku_list,
            "total_count":total_count,
            "total_money":total_money,
            "freight":freight,
            "pay_money":pay_money

        }
        return render(request,'place_order.html',context)


# 保存订单
class CommitOrderView(LoginRequiredMixin,View):
    def post(self,request):
        # 接收
        data = json.loads(request.body.decode())
        address_id = data.get("address_id")
        pay_method = data.get("pay_method")
        # 验证
        if not all([address_id,pay_method]):
            return http.JsonResponse({"code":RETCODE.PARAMERR,"errmsg":"参数不完整"})
        # 处理
        user = request.user
        # 总数量
        total_count = 0
        # 总金额
        total_amount = 0
        # 订单编号 年月日十分秒用户九位ID  2022 05 02 15 27 38 000000001
        now = datetime.now()
        # order_id = now.strftime("%Y%m%d%H%M%S") + "%09d"%user.id
        order_id = random.randint(10000000,99999999)
        # 关闭自动提交
        with transaction.atomic():
            # 开启事务
            sid = transaction.savepoint()
            # 创建基本订单对象
            order = OrderInfo.objects.create(
                order_id=order_id,
                user_id=user.id,
                address_id=address_id,
                total_count=total_count,
                total_amount=total_amount,
                freight=10,
                pay_method=pay_method,
                status=1
            )
            # 查询购物车中选中的商品
            redis_cli = get_redis_connection("cart")
            # 查hash
            cart_dict = redis_cli.hgetall("cart_%d"%user.id) # {b'1':b'2'}
            # 查set
            cart_list = redis_cli.smembers("selected_%d"%user.id)  # [b'1',b'2',b'3']
            # 所有的购物车数据
            cart_dict = {int(sku_id):int(count) for sku_id,count in cart_dict.items()} # {1:2}
            # 集合中的选中列表
            cart_list = [int(sku_id) for sku_id in cart_list]  # [1,2]
            # 查询库存商品对象
            skus = SKU.objects.filter(id__in=cart_list,is_launched=True)  #[<1>,<2>,<3>]
            # 遍历
            for sku in skus:
                # 判断库存
                if cart_dict[sku.id] > sku.stock:
                    # 回滚事物
                    transaction.savepoint_rollback(sid)
                    return http.JsonResponse({"code":RETCODE.STOCKERR,"errmsg":"库存不足！"})
                # 老库存 1   1
                old_stock = sku.stock
                # 新库存  0    0
                new_stock = sku.stock - cart_dict[sku.id]
                # 销量 1  1
                sales = sku.sales + old_stock
                # 模拟延迟 laowang  shuaige
                # time.sleep(5)
                # 使用乐观锁进行修改库存
                res = SKU.objects.filter(id=sku.id,stock=old_stock).update(stock=new_stock,sales=sales)
                # 如果返回结果为0说明没有更新成功
                if res == 0:
                    # 回滚事物
                    transaction.savepoint_rollback(sid)
                    return http.JsonResponse({"code":RETCODE.STOCKERR,"errmsg":"您的手太慢了！"})

                # 修改库存和销量
                # sku.stock -= cart_dict[sku.id]
                # sku.sales += cart_dict[sku.id]
                # sku.save()
                # 创建订单商品表
                OrderGoods.objects.create(
                    order_id=order_id,
                    sku_id=sku.id,
                    count=cart_dict[sku.id],
                    price=sku.price
                )
                # 计算总数量和总金额
                total_count += cart_dict[sku.id]
                total_amount +=  cart_dict[sku.id]*sku.price
            # 修改订单基本表中的总数量和总金额
            order.total_count = total_count
            order.total_amount = total_amount + 10
            order.save()
            # 提交事物
            transaction.savepoint_commit(sid)
        # 删除购物车中选中的商品数据  {1:2,2:2,3:2}  [1,2]
        redis_cli.hdel("cart_%d"%user.id,*cart_list)
        redis_cli.delete("selected_%d"%user.id)
        # 响应
        return http.JsonResponse({
            "code":RETCODE.OK,
            "errmsg":"OK",
            "order_id":order_id
        })


# 展示订单提交成功页面
class SuccessOrderView(LoginRequiredMixin,View):
    def get(self,request):
        # 接收
        order_id = request.GET.get("order_id")
        payment_amount = request.GET.get("payment_amount")
        pay_method = request.GET.get("pay_method")
        # 验证
        if not all([order_id,payment_amount,pay_method]):
            return render(request,'404.html')
        # 处理
        context = {
            "order_id":order_id,
            "payment_amount":payment_amount,
            "pay_method":pay_method
        }
        return render(request,'order_success.html',context)

# 我的订单
class MyOrderView(LoginRequiredMixin,View):
    def get(self,request,page_num):
        # 处理
        user = request.user
        # 查询订单基本表
        orders = OrderInfo.objects.filter(user_id=user.id).order_by("-create_time")
        # 创建分页对象 参数一：对谁进行分页 参数二：分页后每页显示几条数据
        paginator = Paginator(orders,2)  # [1,2],   3,4,    5,6]
        # 获取当前页数据 page_num页码
        current_page = paginator.page(page_num)
        # 构建前端所需要的格式
        order_list = []
        for order in current_page:
            # 订单商品列表
            sku_list = []
            for sku_order in order.skus.all():
                sku_list.append({
                    "default_image":sku_order.sku.default_image.url,
                    "name":sku_order.sku.name,
                    "price":sku_order.price,
                    "count":sku_order.count,
                    "total":sku_order.price*sku_order.count

                })

            order_list.append({
                "create_time":order.create_time.strftime("%Y-%m-%d %H:%M:%S"),
                "order_id":order.order_id,
                "sku_list":sku_list,
                "total_amount":order.total_amount,
                "freight":order.freight,
                "status":order.status
            })

        # 响应
        context = {
            "order_list":order_list,
            # 当前页码
            "page_num":page_num,
            # 总页码
            "total_page":paginator.num_pages
        }

        return render(request,"user_center_order.html",context)


class CommentView(LoginRequiredMixin,View):
    def get(self,request):
        # 接收
        order_id = request.GET.get("order_id")
        # 验证
        try:
            order = OrderInfo.objects.get(order_id=order_id)
        except:
            return http.JsonResponse({"code":RETCODE.PARAMERR,"errmsg":"订单编号无效"})
        # 处理
        # 获取所有的订单商品
        order_goods_list = order.skus.filter(is_commented=False)
        skus = []
        for order_goods in order_goods_list:
            skus.append({
                "price":str(order_goods.price),
                "name":order_goods.sku.name,
                "default_image_url":order_goods.sku.default_image.url,
                "order_id":order_id,
                "sku_id":order_goods.sku.id,
            })
        context = {
            "skus":skus
        }
        # 响应
        return render(request,"goods_judge.html",context)

    def post(self,request):
        # 接收
        param_dict = json.loads(request.body.decode())
        order_id = param_dict.get("order_id")
        sku_id = param_dict.get("sku_id")
        comment = param_dict.get("comment")
        score = param_dict.get("score")
        is_anonymous = param_dict.get("is_anonymous")
        # 验证
        if not all([order_id,sku_id,comment,score]):
            return http.JsonResponse({"code":RETCODE.PARAMERR,"errmsg":"参数不完整"})
        try:
            order = OrderInfo.objects.get(order_id=order_id)
        except:
            return http.JsonResponse({"code":RETCODE.PARAMERR,"errmsg":"无效的订单编号"})
        try:
            sku = SKU.objects.get(id=sku_id)
        except:
            return http.JsonResponse({"code":RETCODE.PARAMERR,"errmsg":"无效的库存商品编号"})
        # 处理
        # 查询订单商品对象并修改其评论数据
        order_goods = OrderGoods.objects.get(order_id=order_id,sku_id=sku_id)
        order_goods.comment = comment
        order_goods.score = score
        order_goods.is_anonymous = is_anonymous
        order_goods.is_commented = True
        order_goods.save()
        # 如果订单中所有的商品都已经评价，将订单的状态改为5
        if all([sku.is_commented for sku in order.skus.all()]):
            order.status = 5
            order.save()
        # 响应
        return http.JsonResponse({"code":RETCODE.OK,"errmsg":"评价成功"})

# 详情页评论展示
class DetailCommentView(View):
    def get(self,request,sku_id):
        # 验证
        try:
            sku = SKU.objects.get(id=sku_id)
        except:
            return http.JsonResponse({"code":RETCODE.PARAMERR,"errmsg":"无效的sku_id"})
        # 处理
        order_list = sku.ordergoods_set.order_by("-create_time")
        comment_list = []
        for order in order_list:
            comment_list.append({
                "username":"******" if order.is_anonymous else order.order.user.username,
                "comment":order.comment,
                "score":order.score
            })

        # 响应
        return http.JsonResponse({"code":RETCODE.OK,"errmsg":"OK","goods_comment_list":comment_list})

